package steampunk.io;
import java.io.*;
import java.util.Hashtable;
import java.awt.Graphics2D;
import java.awt.image.*;
import javax.imageio.*;

import steampunk.art.SpriteGrid;

public class ImageManager {

	private static Hashtable<String, SpriteGrid> spriteGrids = new Hashtable<String, SpriteGrid>();
	private static Hashtable<String, BufferedImage> loadedImages = new Hashtable<String, BufferedImage>();
	private static Hashtable<String, BufferedImage> sections = new Hashtable<String, BufferedImage>();
	
	/**
	 * Returns the image with the given file name. Images are stored internally
	 * in a cache once they are loaded.
	 * @param name
	 * @return
	 */
	public static BufferedImage getImage(String name) {
		if (loadedImages.containsKey(name)) {
			return loadedImages.get(name);
		}
		
		BufferedImage m = null;
		try {
			File f = InstallManager.getFile("images/" + name);
			System.out.println("Loading " + f);
			m = ImageIO.read(f);
		} catch (IOException e) {
			return null;
		}
		
		loadedImages.put(name, m);
		return m;
	}
	
	private static String sectionKey(String name, int x, int y, int w, int h) {
		StringBuffer key = new StringBuffer(name.length()+8);
		key.append(name);
		key.append("-");
		key.append(x);
		key.append("-");
		key.append(y);
		key.append("-");
		key.append(w);
		key.append("-");
		key.append(h);
		return key.toString();
	}
	
	/**
	 * Returns a section of the image with the given name at the given location.
	 * This section is cached, and so can be retrieved efficiently without recreating
	 * it each time. The down-side of this is that if lots of unique sub-images are
	 * created, this will take up a fair amount of memory.
	 * @param name
	 * @param x
	 * @param y
	 * @param w
	 * @param h
	 * @return
	 */
	public static BufferedImage getSection(String name, int x, int y, int w, int h) {
		String key = sectionKey(name, x, y, w, h);
		if (sections.containsKey(key)) {
			return sections.get(key);
		}

		BufferedImage m = getImage(name);
		if (m == null)
			return null;
		
		BufferedImage sub = new BufferedImage(w, h, m.getType());
		Graphics2D g = sub.createGraphics();
		g.drawImage(m, -x, -y, null);
		g.dispose();
		
		sections.put(key, sub);
		
		return sub;
	}
	
	/**
	 * Returns the SpriteGrid formed from the given image with the given rows and columns.
	 * The result is stored in a cache, which is used if the SpriteGrid is requested a
	 * second time.
	 * @param name - the name of the image file
	 * @param rows - the number of rows of frames (# frames in a column)
	 * @param columns - the number of columns of frames (# frames in a row)
	 * @return
	 */
	public static SpriteGrid getSpriteGrid(String name, int rows, int columns) {
		String key = name + "-" + rows + "-" + columns;
		if (spriteGrids.containsKey(key))
			return spriteGrids.get(key);
		SpriteGrid grid = new SpriteGrid(getImage(name), rows, columns);
		spriteGrids.put(key, grid);
		return grid;
	}
}
